﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ABFW
{
    /// <summary>
    /// 框架主流程,第四层,所有场景AssetBundle管理
    /// 
    /// Description:
    ///     功能:
    ///         1:提取Manifest清单文件,缓存本脚本
    ///         2:以场景为单位，管理整个项目中所有AssetBundle包
    /// </summary>
    public class AssetBundleMgr : MonoBehaviour
    {
        //实例
        private static AssetBundleMgr _Instance;
        private static object _lock = new object();

        //场景集合
        private Dictionary<string, MultiABMgr> _DicAllScenes = new Dictionary<string, MultiABMgr>();
        //AssetBundle(清单文件)系统类
        private AssetBundleManifest _ManifestObj = null;

        private AssetBundleMgr() { }

        /// <summary>
        /// AssetBundle整体管理单例
        /// </summary>
        public static AssetBundleMgr Instance {
            get
            {
                if (_Instance == null)
                {
                    lock (_lock)
                    {
                        if (_Instance == null)
                        {
                            _Instance = new GameObject("_AssetBundleMgr").AddComponent<AssetBundleMgr>();
                        }
                    }
                }
                return _Instance;
            }
        }

        void Awake()
        {
            //加载Manifest清单文件
            StartCoroutine(ABManifestLoader.Instance.LoadManifestFile());
        }

        /// <summary>
        /// 下载AssetBundle指定包
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        /// <param name="abName">AssetBundle包名称</param>
        /// <param name="loadAllCompleteHandle">委托：调用是否完成</param>
        /// <returns></returns>
        public IEnumerator LoadAssetBundlePack(string sceneName,string abName,DelLoadComplete loadAllCompleteHandle)
        {
            //参数检查
            if(string.IsNullOrEmpty(sceneName) || string.IsNullOrEmpty(abName))
            {
                Debug.LogError(GetType() + "/loadAssetBundlePack/ scenesName Or abName Is null");
                yield return null;
            }
            //等待Manifest加载完成,如果没有加载完成,就一直yield return null
            while (!ABManifestLoader.Instance.IsLoadFinish)
            {
                yield return null;
            }
            _ManifestObj = ABManifestLoader.Instance.GetManifest;
            if(_ManifestObj == null)
            {
                Debug.LogError(GetType() + "/loadAssetBundlePack/ _MainfestObj Is null,请先确保加载Manifest不为null");
                yield return null;
            }

            //把当前场景加入集合中
            if (!_DicAllScenes.ContainsKey(sceneName))
            {
                MultiABMgr multiMgrObj = new MultiABMgr(sceneName, abName, loadAllCompleteHandle);
                _DicAllScenes.Add(sceneName, multiMgrObj);
            }

            //调用下一层("多包管理类")
            MultiABMgr tmpMultiMgrObj = _DicAllScenes[sceneName];
            if(tmpMultiMgrObj == null)
            {
                Debug.LogError(GetType() + "/loadAssetBundlePack/ tmpMultiMgrObj Is null");
            }

            //调用多包管理,加载指定AB包
            yield return tmpMultiMgrObj.LoadAssetBundle(abName);
        }

        /// <summary>
        /// 加载AB包中的资源
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        /// <param name="abName">ab包名</param>
        /// <param name="assetName">资源名</param>
        /// <param name="isCache">是否使用缓存</param>
        /// <returns></returns>
        public UnityEngine.Object LoadAsset(string sceneName,string abName,string assetName,bool isCache)
        {
            if (_DicAllScenes.ContainsKey(sceneName))
            {
                MultiABMgr multObj = _DicAllScenes[sceneName];
                return multObj.LoadAsset(abName,assetName,isCache);
            }
            Debug.LogError(GetType() + "/LoadAsset()/无法找到场景名,无法加载AB,场景名是: "+sceneName);
            return null;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="sceneName">场景名 </param>
        public void DisposeAllAssets(string sceneName)
        {
            if (_DicAllScenes.ContainsKey(sceneName))
            {
                MultiABMgr multObj = _DicAllScenes[sceneName];
                multObj.DisposeAllAsset();
            }else
            {
                Debug.LogError(GetType() + "/DisposeAllAssets()/找不到场景名,无法释放资源" + sceneName);
            }
        }


    }
}
